﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public partial class BattleManager {

	//public BattleManager manager;

	List<BattlePawn> validTargets = new List<BattlePawn>();
	List<BattlePawn> targetSeleted = new List<BattlePawn>();
	
	public BattlePawn [] GetTarget(bool _isPlayer, bool isSameSide, int numTarget)
	{
		if(isSameSide)
			_isPlayer = !_isPlayer;
		validTargets.Clear();
		targetSeleted.Clear();
		if(_isPlayer) {
			foreach(BattlePawn pawn in targetableEnemyList)
				validTargets.Add(pawn);
		}
		else {
			foreach(BattlePawn pawn in targetablePlayerList)
				validTargets.Add(pawn);
		}
		
		while(numTarget>0 && validTargets.Count>0)
		{
			int nIndex = Well512.Instance.NextInt(validTargets.Count);
			targetSeleted.Add(validTargets[nIndex]);
			validTargets.RemoveAt(nIndex);
			numTarget--;
		}
		
		return targetSeleted.ToArray();
	}
	
	public BattlePawn GetEnemyTargetable(int _no)
	{
		foreach(BattlePawn pawn in targetableEnemyList)
			if(pawn.mNo == _no)
				return pawn;
		return null;
	}
	
	public BattlePawn GetPlayerTargetable(int _no)
	{
		foreach(BattlePawn pawn in targetablePlayerList)
			if(pawn.mNo == _no)
				return pawn;
		return null;
	}
	
	public BattlePawn GetTargetOneByTaunt(bool _isPlayer)
	{
		BattlePawn pawn = BattleCheat.Instance.CheckInfiniteTurnDefender(_isPlayer);
		if(pawn!=null)
			return pawn;
		
		if(_isPlayer)
			return BattleFormula.GetTargetByTaunt(targetableEnemyList);
		else
			return BattleFormula.GetTargetByTaunt(targetablePlayerList);
	}

	public BattlePawn GetTargetOne5vs5(BattlePawn attackPawn)
	{
		int nFrontLine = attackPawn.myCurLine;
		if(attackPawn.isPlayer) {
			if(targetableEnemyList.Count==0)
				return null;
			nFrontLine++;
			if(nFrontLine==6)
				return null;
			validTargets.Clear();
			int nCount = targetableEnemyList.Count;
			for(int i=0; i<nCount; i++) {
				if(attackPawn.attackRange==0 && targetableEnemyList[i].myCurLine==nEnemyFrontLine)
					validTargets.Add (targetableEnemyList[i]);
				if(attackPawn.attackRange==1 && (targetableEnemyList[i].myCurLine==nEnemyFrontLine || targetableEnemyList[i].myCurLine==nEnemyFrontLine+1 )  )
					validTargets.Add (targetableEnemyList[i]);
			}
			if(validTargets.Count>0) {
				return validTargets[ Random.Range(0, validTargets.Count)];
			}
			else
				return targetableEnemyList[ Random.Range(0, targetableEnemyList.Count)];
		}
		else {
			if(targetablePlayerList.Count==0)
				return null;
			nFrontLine--;
			if(nFrontLine<0)
				return null;
			validTargets.Clear();
			int nCount = targetablePlayerList.Count;
			for(int i=0; i<nCount; i++) {
				if(attackPawn.attackRange==0 && targetablePlayerList[i].myCurLine==nPlayerFrontLine)
					validTargets.Add (targetablePlayerList[i]);
				if(attackPawn.attackRange==1 && (targetablePlayerList[i].myCurLine==nPlayerFrontLine || targetablePlayerList[i].myCurLine==nPlayerFrontLine-1)  )
					validTargets.Add (targetablePlayerList[i]);
			}
			if(validTargets.Count>0) {
				return validTargets[ Random.Range(0, validTargets.Count)];
			}
			else
				return targetablePlayerList[ Random.Range(0, targetablePlayerList.Count)];
		}
	}

	public BattlePawn[] GetTargetTwoByTaunt(bool _isPlayer)
	{
		List<BattlePawn> pawnList;
		validTargets.Clear();
		if(_isPlayer)
			pawnList = targetableEnemyList.GetRange(0, targetableEnemyList.Count);
		else
			pawnList = targetablePlayerList.GetRange(0, targetablePlayerList.Count);
		
		BattlePawn selectedPawn = BattleFormula.GetTargetByTaunt(pawnList);
		validTargets.Add( selectedPawn );
		if(pawnList.Count>=2) {
			pawnList.Remove(selectedPawn);
			validTargets.Add( BattleFormula.GetTargetByTaunt(pawnList) );
		}
		return validTargets.ToArray();
	}
	
	public BattlePawn GetTargetRandom(bool _isPlayer, bool isSameSide)
	{
		if(isSameSide)
			_isPlayer = !_isPlayer;
		if(_isPlayer)
		{
			if(targetableEnemyList.Count==0)
				return null;
			int nIndex = Well512.Instance.NextInt(targetableEnemyList.Count);
			return targetableEnemyList[nIndex];
		}
		else
		{
			if(targetablePlayerList.Count==0)
				return null;
			int nIndex = Well512.Instance.NextInt(targetablePlayerList.Count);
			return targetablePlayerList[nIndex];
		}
	}

	public BattlePawn [] GetPawnAll(bool _isPlayer, bool isSameSide)
	{
		if(isSameSide)
			_isPlayer = !_isPlayer;
		if(_isPlayer)
		{
			return enemyList.ToArray();
		}
		else
		{
			return playerList.ToArray();
		}
	}

	public BattlePawn [] GetTargetAll(bool _isPlayer, bool isSameSide)
	{
		if(isSameSide)
			_isPlayer = !_isPlayer;
		if(_isPlayer)
		{
			return targetableEnemyList.ToArray();
		}
		else
		{
			return targetablePlayerList.ToArray();
		}
	}
	/*
	 * hp가 가장 낮은 아군 찾음
	public BattlePawn GetHealTarget(bool _isPlayer)
	{
		BattlePawn minHpPawn = null;
		int minHp = 0;
		if(_isPlayer)
		{
			foreach(BattlePawn pawn in targetablePlayerList)
			{
				if(!pawn.IsMaxHP() && (minHp==0 || pawn.hp<=minHp) )
				{
					minHp = pawn.hp;
					minHpPawn = pawn;
				}
			}
		}
		else
		{
			foreach(BattlePawn pawn in targetableEnemyList)
			{
				if(!pawn.IsMaxHP() && (minHp==0 || pawn.hp<=minHp) )
				{
					minHp = pawn.hp;
					minHpPawn = pawn;
				}
			}
		}
		return minHpPawn;
	}*/
	
	public BattlePawn [] GetHealTargetAll(bool _isPlayer)
	{
		validTargets.Clear();
		if(_isPlayer)
		{
			foreach(BattlePawn pawn in targetablePlayerList)
			{
				//if(pawn.isDead == true)
				//	continue;
				//if(!pawn.IsMaxHP())
				validTargets.Add (pawn);
			}
		}
		else
		{
			foreach(BattlePawn pawn in targetableEnemyList)
			{
				//if( pawn.isDead == true )
				//	continue;
				//if(!pawn.IsMaxHP())
				validTargets.Add (pawn);
			}
		}
		return validTargets.ToArray();
	}
	
	public void AddToTargetList(BattlePawn pawn, bool _isPlayer)
	{
		if(_isPlayer)
			targetablePlayerList.Add(pawn);
		else
			targetableEnemyList.Add(pawn);
	}

	public bool IsLineEmpty(int line)
	{
		for(int i=0; i<5; i++) {
			if( Battle5vs5Center.Instance.isOccupied[line, i])
				return false;
		}
		return true;
	}
	
	public void RemoveFromTargetList5vs5(BattlePawn pawn, bool _isPlayer)
	{
		Battle5vs5Center.Instance.SetOccupied(pawn, false);

		if(_isPlayer)
		{
			if(targetablePlayerList.Contains(pawn) )
				targetablePlayerList.Remove(pawn);

			if(targetablePlayerList.Count==0)
				return;
			int prevFrontLine = nPlayerFrontLine;
			nPlayerFrontLine = 0;
			foreach(BattlePawn _pawn in targetablePlayerList) {
				if(_pawn.WillBeLine> nPlayerFrontLine)
					nPlayerFrontLine = _pawn.WillBeLine;
			}
			Debug.Log("enemy move forward  "+prevFrontLine+"  "+nPlayerFrontLine);
			int nStepSize = prevFrontLine - nPlayerFrontLine;
			if(nStepSize>0) {

				foreach(BattlePawn enemy in targetableEnemyList) {
					enemy.ShouldMoveForward(nStepSize);
				}
				Debug.Log("nEnemyFrontLine "+nEnemyFrontLine+" minus "+nStepSize);
				nEnemyFrontLine-=nStepSize;
			}

		}
		else
		{
			if(targetableEnemyList.Contains(pawn) )
				targetableEnemyList.Remove(pawn);
			if(targetableEnemyList.Count==0)
				return;
			int prevFrontLine = nEnemyFrontLine;
			nEnemyFrontLine=5;
			foreach(BattlePawn _pawn in targetableEnemyList) {
				if(_pawn.WillBeLine< nEnemyFrontLine)
					nEnemyFrontLine = _pawn.WillBeLine;
			}
			Debug.Log("player move forward  "+prevFrontLine+"  "+nEnemyFrontLine);
			int nStepSize = nEnemyFrontLine - prevFrontLine;
			if(nStepSize>0) {

				foreach(BattlePawn enemy in targetablePlayerList) {
					enemy.ShouldMoveForward(nStepSize);
				}
				Debug.Log("nPlayerFrontLine "+nPlayerFrontLine+" plus "+nStepSize);
				nPlayerFrontLine+=nStepSize;
			}

		}
		
	}

	public void RemoveFromTargetList(BattlePawn pawn, bool _isPlayer)
	{
		if(_isPlayer)
		{
			if(targetablePlayerList.Contains(pawn) )
				targetablePlayerList.Remove(pawn);
		}
		else
		{
			if(targetableEnemyList.Contains(pawn) )
				targetableEnemyList.Remove(pawn);
		}
	}

	public void IncreaseRage(int damage, int maxHp)
	{
		IncreaseRage(damage, maxHp, 0);
	}
	public void IncreaseRage(int damage, int maxHp, float forceDeltaRage)
	{
		float deltaRage = 0;

		if(forceDeltaRage==0) {
			deltaRage = BattleFormula.GetDeltaRage(damage, maxHp);

			//시연용 고정 25//
			deltaRage = 25;

			if(BattleCheat.Instance.deltaRage>=0)
				deltaRage = BattleCheat.Instance.deltaRage;
		}
		else
			deltaRage = forceDeltaRage;

//		Debug.Log("delta rage = "+deltaRage);
		rageValue += deltaRage;
		if(rageValue>=100)
		{
			rageValue=100;
			//isRageSkillCastable=true;
		}
		UserData.Instance.rageValue = rageValue;
		SetSuperGage();	
	}

	public void SetSuperGage()
	{
		if(Is5vs5New)
			return;
		BattleUIManager.Instance.SetSuperGage((int)rageValue);
//		BattleUIManager.Instance.ShowSuperGageFX();	
	}

	void ClearRage()
	{
		rageValue = 0;
		UserData.Instance.rageValue = 0;
	}

	public static float minRageForUltimate = 50.0f;//필살기 사용위한 게이지값//
	public void UseRageSkill()
	{
		Debug.Log("UseRageSkill");
//		if(rageValue>=minRageForUltimate)
//		{
			if(rageValue==100) {//오버드라이브 모드
				SetOverdriveMode();
				ClearRage();
				Invoke ("ShowSuperGageBrokenOutAnimation",0.5f);
			}
//			else {//필살기
//				PrepareRageSkill();
//			}
//
//		}
	}

	public bool CanUseRageSkill()
	{
		if(rageValue<minRageForUltimate)
			return false;
		if(isGameOver)
			return false;
		return true;
	}

	void ShowSuperGageBrokenOutAnimation()
	{
		BattleUIManager.Instance.ShowSuperGageBrokenOutAnimation();
	}

//	void CheckPawnIdle()
//	{
//		foreach(BattlePawn pawn in playerList)
//			pawn.CheckPlayIdle2();
//		foreach(BattlePawn pawn in enemyList)
//			pawn.CheckPlayIdle2();
//	}
//
//	void Update()
//	{
//		CheckPawnIdle();
//	}

	public bool IsAllPawnIdle()
	{
		foreach(BattlePawn pawn in playerList) {
			if( pawn.CanDoAction() && !pawn.pawnManifest.IsIdlePlaying() )
				return false;
		}
		foreach(BattlePawn pawn in enemyList) {
			if( pawn.CanDoAction() && !pawn.pawnManifest.IsIdlePlaying() )
				return false;
		}
		return true;
	}


	// 아군 모두 버스트 치트//
//	public int totalBurstAtkCount;
//	public int burstAtkCount;
//	public bool bBurstAllCheat;
//	public void SetNextTurnBurstAll()
//	{
//		bBurstAllCheat=true;
//		burstAtkCount=0;
//		totalBurstAtkCount=0;
//		BattleCheat.Instance.alwaysBurst = true;
//		foreach(BattlePawn pawn in playerList) {
//			if(pawn.CanDoAction() ) {
//				totalBurstAtkCount++;
//			}
//		}
//		Debug.Log("SetNextTurnBurstAll   total="+totalBurstAtkCount);
//	}

	//오버드라이브 모드. 화면을 터치할때마다 원호 공격 액션을 취하는 일반 공격을 발동한다 //
	public bool bOverdriveMode;
	public bool isOverdriveReady;
	public void SetOverdriveMode()
	{
		if(bOverdriveMode)
			return;
		isOverdriveReady=false;
		bOverdriveMode = true;
	}

	public void StartOverdriveMode()
	{
		if(CamTakeSetting.Instance!=null) {
			CamTakeSetting.Instance.allowTouchCam=false;
			CamTakeSetting.Instance.DeactivateFreeCam();
		}
		GameObject.Find("UI Root").transform.FindChild("TestPanelBlank").gameObject.SetActive (true);
		BattleUIManager.Instance.HideBattleUI();
		isOverdriveReady=true;
		Time.timeScale = BattleSetting.Instance.overdriveModeTimeScale;
		StartCoroutine("CoOverdriveMode");
	}

	public void EndOverdriveMode()
	{
		if(bOverdriveMode) {
			StopCoroutine("CoOverdriveMode");
			EndOverdrive();
		}
	}

	void EndOverdrive()
	{
		if(CamTakeSetting.Instance!=null) 
			CamTakeSetting.Instance.allowTouchCam=true;
		Time.timeScale = 1;
		isOverdriveReady=false;
		bOverdriveMode = false;
		BattleUIManager.Instance.battleUIObject.SetActive(true);
		GameObject.Find("UI Root").transform.FindChild("TestPanelBlank").gameObject.SetActive (false);
		UpdateEnemyHP();
		BattleUIManager.Instance.HideOverDriveTimer();
	}

	IEnumerator CoOverdriveMode()
	{
		float sumTime=0;
		while(true)
		{
			sumTime += Time.deltaTime;
			if(sumTime>=BattleSetting.Instance.overdriveModeTime)
				break;
			yield return null;
		}

		EndOverdrive();
	}

	//아군 플레이어중 공격 가능한 한명을 골라 공격시킨다.//
	List<BattlePawn> overdriveAtkCandidates = new List<BattlePawn>();
	public void TryOverdriveAttack()
	{
		if(!isOverdriveReady)
			return;
		overdriveAtkCandidates.Clear();
		foreach(BattlePawn pawn in playerList) {
			if(pawn.CanDoAction() && pawn.pawnManifest.IsIdlePlaying() )
				overdriveAtkCandidates.Add ( pawn);
		}
		if(overdriveAtkCandidates.Count>0) {
			BattlePawn atkPawn = overdriveAtkCandidates[ Random.Range(0, overdriveAtkCandidates.Count) ];
			Debug.Log("Overdrive Attack   "+atkPawn.pawnManifest.name);
			atkPawn.DoAction();
		}
	}



}
